﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using AdoNet = System.Data;
using System.Runtime.CompilerServices;

namespace DataSet4Com
{
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.AutoDispatch)]
    [ComDefaultInterface(typeof(IDataRelationCollection))]
    [Guid("4842B769-163A-4D1A-B192-EF474DE22F0E")]
    public class DataRelationCollection : IDataRelationCollection, IEnumerable
    {
        private AdoNet.DataRelationCollection _adoNetRelationCollection;

        public DataRelationCollection() : this(null) { }

        public DataRelationCollection(AdoNet.DataRelationCollection adoNetRelationCollection)
        {
            if (adoNetRelationCollection == null)
                throw new ArgumentNullException("adoNetRelationCollection");
            else
                _adoNetRelationCollection = adoNetRelationCollection;
        }

        [ComVisible(false)]
        public AdoNet.DataRelationCollection AdoNetDataRelationCollection
        {
            get { return _adoNetRelationCollection; }
        }

        [DispId(-4)]
        public IEnumerator GetEnumerator()
        {
            var result = from AdoNet.DataRelation relation in _adoNetRelationCollection
                         select new DataRelation(relation);

            return result.GetEnumerator();
        }

        [DispId(0)]
        [IndexerName("_Default")]
        public DataRelation this[int index]
        {
            get
            {
                return new DataRelation(_adoNetRelationCollection[index]);
            }
        }

        public DataRelation GetRelationByName(string name)
        {
            return new DataRelation(_adoNetRelationCollection[name]);
        }

        public virtual DataRelation Add(string name, DataColumn parentColumn, DataColumn childColumn, [Optional, DefaultParameterValue(true)] bool createConstraints)
        {            
            return new DataRelation(_adoNetRelationCollection.Add(name, parentColumn.AdoNetDataColumn, childColumn.AdoNetDataColumn, createConstraints));         
        }

        public virtual DataRelation AddWithMultipleKeys(string name, DataColumnList parentColumns, DataColumnList childColumns, [Optional, DefaultParameterValue(true)] bool createConstraints)
        { 
            AdoNet.DataColumn[] adoNetParentColumns = (from column in parentColumns.InternalList
                                                       select column.AdoNetDataColumn).ToArray();

            AdoNet.DataColumn[] adoNetChildColumns = (from column in childColumns.InternalList
                                                       select column.AdoNetDataColumn).ToArray();

            return new DataRelation(_adoNetRelationCollection.Add(name, adoNetParentColumns, adoNetChildColumns, createConstraints));
        }

        public virtual bool CanRemove(DataRelation relation)
        {
            return _adoNetRelationCollection.CanRemove(relation.AdoNetDataRelation);
        }

        public virtual void Clear()
        {
            _adoNetRelationCollection.Clear();
        }

        public virtual bool Contains(string name)
        {
            return _adoNetRelationCollection.Contains(name);
        }

        public virtual int IndexOfRelation(DataRelation relation)
        {
            return _adoNetRelationCollection.IndexOf(relation.AdoNetDataRelation);
        }

        public virtual int IndexOf(string relationName)
        {
            return _adoNetRelationCollection.IndexOf(relationName);
        }

        public void RemoveRelation(DataRelation relation)
        {
            _adoNetRelationCollection.Remove(relation.AdoNetDataRelation);
        }

        public void Remove(string name)
        {
            _adoNetRelationCollection.Remove(name);
        }

        public void RemoveAt(int index)
        {
            _adoNetRelationCollection.RemoveAt(index);
        }

        public int Count
        {
            get { return _adoNetRelationCollection.Count; }
        }
    }

    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    [Guid("DB890C5D-9C00-4440-84C2-ABFCBE8FFB78")]
    public interface IDataRelationCollection
    {
        [DispId(-4)]
        IEnumerator GetEnumerator();

        [DispId(0)]
        [IndexerName("_Default")]
        DataRelation this[int index]
        {
            get;
        }

        DataRelation GetRelationByName(string name);

        DataRelation Add(string name, DataColumn parentColumn, DataColumn childColumn, [Optional, DefaultParameterValue(true)] bool createConstraints);

        DataRelation AddWithMultipleKeys(string name, DataColumnList parentColumns, DataColumnList childColumns, [Optional, DefaultParameterValue(true)] bool createConstraints);

        bool CanRemove(DataRelation relation);

        void Clear();

        bool Contains(string name);

        int IndexOfRelation(DataRelation relation);

        int IndexOf(string relationName);

        void RemoveRelation(DataRelation relation);

        void Remove(string name);

        void RemoveAt(int index);

        int Count
        {
            get;
        }
    }
}
